/*+***********************************************************************************
 Filename: 03_tinycore_step04\src\peripheral.v
 Description: a module to hold all kinds of peripherals.

 Modification:
   2022.11.07 Creation   H.Zheng

Copyright (C) 2022  Zheng Hui (hzheng@gzhu.edu.cn)

License: MulanPSL-2.0

***********************************************************************************-*/

module peripheral (
    //from top
    input wire clk,
    input wire reset_n,
    input wire button,
    output wire [5:0] led,
    input wire rxd,
    output wire txd,
    //from core
    input wire ce, //chip enable
    input wire wre, //write enable
    input wire [8:0] addr, //address bus
    input wire [31:0] data_in,
    output wire [31:0] data_out
);
    //gpio
    //
    wire gpio_ce = (ce & (addr[8:2] == 7'b0)) ? 1'b1 : 1'b0;

    wire [31:0] gpio_data_out;
    gpio m_gpio(
        .clk(clk),
        .reset_n(reset_n),
        .button(button),
        .led(led),
        .ce(gpio_ce),
        .wre(wre),
        .addr(addr[1:0]),
        .data_in(data_in),
        .data_out(gpio_data_out)

    );

    //uart
    //
    wire uart_ce = (ce & (addr[8:2] == 7'b0000001)) ? 1'b1 : 1'b0;

    wire [31:0] uart_data_out;

    peripheral_uart m_uart0(
        .clk(clk),
        .reset_n(reset_n),
        .rxd(rxd),
        .txd(txd),
        .ce(uart_ce),
        .wre(wre),
        .addr(addr[1:0]),
        .data_in(data_in),
        .data_out(uart_data_out)
    );

    //data out mux
    assign data_out = (gpio_ce) ? gpio_data_out :
                        (uart_ce) ? uart_data_out : 32'bz;

endmodule
